import datetime
import json

import requests
from fastapi import APIRouter
from parsel import Selector

from re_common.baselibrary.utils.baserequest import BaseRequest

from apps.allsubdb.proxies_control.models import PostProxy
from apps.core.global_model import InputPlatformModel
from apps.core.m_route import ContextIncludedRoute
from apps.core.return_info import ReturnInfo, FAILED, SUCCESS
from apps.crawler_platform.core_platform.g_model import CnkiPdf

router = APIRouter(route_class=ContextIncludedRoute)

class DownCnkiPdfUrl(object):
    def __init__(self, journal_rawid, pub_year, num):

        self.bsrequest = BaseRequest()
        self.url1 = "https://navi.cnki.net/knavi/journals/{}/yearList"
        self.url2 = "https://navi.cnki.net/knavi/journals/{}/papers?yearIssue={}&pageIdx=0&pcode=CJFD,CCJD"
        self.pdf_list = list()
        self.headers = {"Accept": "*/*", "Accept-Encoding": "gzip, deflate, br",
                        "Content-Type": "application/x-www-form-urlencoded;charset=UTF-8",
                        "Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6",
                        "Host": "navi.cnki.net",
                        "Origin": "https://navi.cnki.net",
                        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36 Edg/119.0.0.0"
                        }
        self.counts = 0
        self.journal_rawid = journal_rawid
        self.pub_year = pub_year
        self.num = num

    def get_proxy(self):
        url = "http://192.168.31.219:8001/proxies_control/proxies_management/getproxy/secret_proxy_test?is_all=0"
        r = requests.get(url)
        html = r.text
        proxy = json.loads(html)['data']
        return proxy

    def getNowTime(self):
        return datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')


    def refrehsession(self):
        self.proxy = self.get_proxy()
        self.bsrequest.set_sn()
        self.bsrequest.is_use_proxy(True)
        self.bsrequest.set_proxy(self.proxy)

    def get_uid(self):
        # 学校代理分配的uid  有这个才能下PDF
        headers = self.headers.copy()
        headers["Host"] = "login.cnki.net"
        url = "https://login.cnki.net/TopLoginNew/api/loginapi/IpLoginFlush?callback=jQuery"
        b, e, r = self.bsrequest.base_request(url, headers=headers, timeout=20)
        if b:
            text = r.text.replace("jQuery(", "").rstrip(")")
            text_json = json.loads(text)
            self.uid = text_json["Uid"]
            # print(self.uid)
            self.ShowName = text_json["ShowName"]

    def parse_first(self, html):
        judge_year = self.pub_year
        sel = Selector(html, type="html")
        ppp = sel.css("#YearIssueTree .yearissuepage")
        for item in ppp:
            aaa = item.css("dl")
            for a in aaa:
                year = a.css("dt em::text").get().strip()
                issue_format = "No." + self.num
                indexs = a.css("dd a")
                if year == judge_year:
                    for index in indexs:
                        value = index.css("a::attr(value)").get()
                        issue_2 = index.css("a::text").get()
                        if issue_2 == issue_format:
                            return value

    def down_before_first(self):
        journal_rawid = self.journal_rawid
        headers_cnki_list = {
            'Accept': '*/*',
            'Accept-Encoding': 'gzip, deflate, br',
            'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8',
            'Referer': f'https://navi.cnki.net/knavi/journals/{journal_rawid}/detail?uniplatform=NZKPT',
            'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6',
            'Host': 'navi.cnki.net',
            'Origin': 'https://navi.cnki.net',
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36 Edg/119.0.0.0'
        }
        url = f'https://navi.cnki.net/knavi/journals/{journal_rawid}/detail?uniplatform=NZKPT'
        b, e, r = self.bsrequest.base_request_post(url=url, headers=headers_cnki_list, marks=["titbox"],
                                                   sn=self.bsrequest.sn,
                                                   timeout=30)
        if b:
            time_str, pCode = self.parse_before_first(r.text)
            return True, time_str, pCode
        else:
            return False, "", ""

    def parse_before_first(self, html):
        sel = Selector(html, type="html")
        time_str = sel.css('input[id="time"]::attr(value)').get()
        pCode = sel.css('input[id="pCode"]::attr(value)').get()
        return time_str, pCode

    def down_first(self, time_str):
        headers = self.headers.copy()
        headers["Referer"] = "https://navi.cnki.net/knavi/journals/{}/detail?uniplatform=NZKPT".format(self.journal_rawid)
        headers["Host"] = "navi.cnki.net"
        # headers["Origin"] = "https://navi.cnki.net"
        # headers["Accept"] = "*/*"
        # headers["Accept-Encoding"] = "gzip, deflate"
        # headers["Accept-Language"] = "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6"
        # headers["Content-Type"] = "application/x-www-form-urlencoded;charset=UTF-8"

        post_data = {
            "pIdx": "0",
            "time": f"{time_str}",
        }

        b, e, r = self.bsrequest.base_request_post(url=self.url1.format(self.journal_rawid), data=post_data, headers=headers, sn=self.bsrequest.sn,
                                                   timeout=30)
        if b:

            value = self.parse_first(r.text)
            return True, value
        else:
            return False, ""

    def parse_second(self, html):
        sel = Selector(html, type="html")
        app = sel.css("div dd[class~='clearfix']")
        for article in app:
            # url = article.css("a::attr(href)").get().strip()
            title_list = article.css(".name a::text,.name a>*::text").getall()
            title = "".join(title_list)
            new_url_test = "".join(article.css(".name a::attr(href),.name a>*::attr(href)").getall())
            rawid = article.css('b[name="encrypt"]::attr(id)').get()
            self.pdf_list.append((rawid, title, new_url_test))


    def down_second(self, value):
        headers = self.headers.copy()
        headers["Referer"] = "https://navi.cnki.net/knavi/journals/{}/detail?uniplatform=NZKPT".format(self.journal_rawid)
        headers["Host"] = "navi.cnki.net"
        b, e, r = self.bsrequest.base_request_post(self.url2.format(self.journal_rawid, value),
                                                   self.bsrequest.sn, headers=headers, timeout=30)
        if b:
            self.parse_second(r.text)
        return b



    def run(self):
        self.refrehsession()
        self.get_uid()
        dic = dict()
        bry, time_str, pCode =self.down_before_first()
        if bry:
            b, v = self.down_first(time_str)
            if b:
                bools = self.down_second(v)
                if bools:
                    for data in self.pdf_list:
                        new_dic = dict()

                        new_dic["title"] = data[1]
                        new_dic["url"] = data[2]
                        dic[data[0]] = new_dic
                    return True, dic
                else:
                    return False, dic
            else:
                return False, dic
        else:
            return False, dic


@router.post("/get_urls")
async def get_one_file2(input: InputPlatformModel[CnkiPdf]):
    return_info = ReturnInfo()
    # 将就用这个model
    journal_rawid = input.data.journal_rawid
    pub_year = input.data.pub_year
    num = input.data.num

    ddd = DownCnkiPdfUrl(journal_rawid, pub_year,num)
    br, dic = ddd.run()
    if br:
        return_info.status = SUCCESS
        return_info.msg_code = 200
        return_info.msg = ""
        return_info.data = dic
        return return_info.todict()
    else:
        return_info.status = FAILED
        return_info.msg_code = 400
        return_info.msg = ""
        return_info.data = {}
        return return_info.todict()
